package ru.papergames;

import org.apache.log4j.Logger;
import ru.papergames.battleserver.util.FloodProtectorConfig;
import ru.papergames.battleserver.util.PaperGamesProperties;
import ru.papergames.battleserver.util.StringUtil;

import java.io.File;
import java.io.InputStream;

public final class Config
{
	protected static final Logger _log = Logger.getLogger(Config.class.getName());

	//--------------------------------------------------
	// Oside Battle Property File Definitions
	//--------------------------------------------------

    public static final String FLOOD_PROTECTOR_FILE = "./config/floodprotector.properties";
    public static final String MMO_CONFIG_FILE = "/config/mmo.properties";
    public static final String CONFIGURATION_FILE = "/config/server.properties";
    public static final String TELNET_CONFIG_FILE = "/config/telnet.properties";


    public static boolean DEBUG;
    public static boolean DEVELOPER = true;

	//--------------------------------------------------
	// FloodProtector Settings
	//--------------------------------------------------
	public static final FloodProtectorConfig FLOOD_PROTECTOR_USE_ITEM =
		new FloodProtectorConfig("UseItemFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_ROLL_DICE =
		new FloodProtectorConfig("RollDiceFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_FIREWORK =
		new FloodProtectorConfig("FireworkFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_ITEM_PET_SUMMON =
		new FloodProtectorConfig("ItemPetSummonFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_HERO_VOICE =
		new FloodProtectorConfig("HeroVoiceFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_GLOBAL_CHAT =
		new FloodProtectorConfig("GlobalChatFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_SUBCLASS =
		new FloodProtectorConfig("SubclassFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_DROP_ITEM =
		new FloodProtectorConfig("DropItemFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_SERVER_BYPASS =
		new FloodProtectorConfig("ServerBypassFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_MULTISELL =
		new FloodProtectorConfig("MultiSellFloodProtector");
	public static final FloodProtectorConfig FLOOD_PROTECTOR_TRANSACTION =
		new FloodProtectorConfig("TransactionFloodProtector");



	//--------------------------------------------------
	// Server Settings
	//--------------------------------------------------
	public static int PORT_FOR_WEB_SERVER;
	public static int SELECTOR_THREAD_SLEEP_FOR_WEB_SERVER;

	public static int PORT_GAME;
	public static int PORT_LOGIN;
	public static String LOGIN_BIND_ADDRESS;
	public static int LOGIN_TRY_BEFORE_BAN;
	public static int LOGIN_BLOCK_AFTER_BAN;
	public static String GAMESERVER_HOSTNAME;
	public static String DATABASE_DRIVER;
	public static String DATABASE_URL;
	public static String DATABASE_LOGIN;
	public static String DATABASE_PASSWORD;
	public static int DATABASE_MAX_CONNECTIONS;
	public static int DATABASE_MAX_IDLE_TIME;
	public static int MAXIMUM_ONLINE_USERS;
	public static String CNAME_TEMPLATE;
	public static String PET_NAME_TEMPLATE;
	public static int MAX_CHARACTERS_NUMBER_PER_ACCOUNT;
	public static File DATAPACK_ROOT;
	public static boolean ACCEPT_ALTERNATE_ID;
	public static int REQUEST_ID;
	public static boolean RESERVE_HOST_ON_LOGIN = false;
	public static int MIN_PROTOCOL_REVISION;
	public static int MAX_PROTOCOL_REVISION;
	public static boolean LOG_LOGIN_CONTROLLER;
    public static boolean DEADLOCK_DETECTOR;
    public static int DEADLOCK_CHECK_INTERVAL;
    public static boolean RESTART_ON_DEADLOCK;
    public static int THREAD_P_EFFECTS;
    public static int THREAD_P_GENERAL;
    public static int GENERAL_PACKET_THREAD_CORE_SIZE;
    public static int WS_PACKET_THREAD_CORE_SIZE;
    public static int IO_PACKET_THREAD_CORE_SIZE;
    public static int GENERAL_THREAD_CORE_SIZE;
    public static int AI_MAX_THREAD;



	//--------------------------------------------------
	// MMO Settings
	//--------------------------------------------------
	public static int MMO_SELECTOR_SLEEP_TIME;
	public static int MMO_MAX_SEND_PER_PASS;
	public static int MMO_MAX_READ_PER_PASS;
	public static int MMO_HELPER_BUFFER_COUNT;
	public static int MMO_IO_SELECTOR_THREAD_COUNT;

	//--------------------------------------------------
	// No classification assigned to the following yet
	//--------------------------------------------------
	public static int MAX_ITEM_IN_PACKET;
	public static boolean CHECK_KNOWN;
	public static int GAME_SERVER_LOGIN_PORT;
	public static String GAME_SERVER_LOGIN_HOST;
	public static String INTERNAL_HOSTNAME;
	public static String EXTERNAL_HOSTNAME;
	public static String ROUTER_HOSTNAME;
	public static int NEW_NODE_ID;
	public static int SELECTED_NODE_ID;
	public static int LINKED_NODE_ID;
	public static String NEW_NODE_TYPE;
	public static int IP_UPDATE_TIME;
	public static String SERVER_VERSION;
	public static String SERVER_BUILD_DATE;
	public static String DATAPACK_VERSION;

    public static boolean PACKET_HANDLER_DEBUG;

    public static int TURN_CONTROLLER_THREAD_COUNT;
    public static int BATTLE_COUNT_IN_ONE_TURN_CONTROLLER;

    public static long CLIENT_SYNC_TIMEOUT;
    public static long BATTLE_INIT_TIMEOUT;

    public static int NPC_CONTROLLER_THREAD_COUNT;
    public static int NPC_COUNT_IN_ONE_NPC_CONTROLLER;

    // Battle play configs:
    public static int AP_PER_TURN;

    public static int AP_MOVE_BALL;
    public static int AP_TOGGLE_DOOR;
    public static int AP_EQUIP_ITEM;
    public static int AP_SWAP_WEAPONS;
    public static int AP_UNSEAL_CONTAINER;
    public static int AP_OPEN_CONTAINER;
    public static int AP_EXCHANGE_ITEMS;
    public static int AP_DROP;

    public static int AP_ATTACK_MELEE;
    public static int AP_ATTACK_KNUCKLES;
    public static int AP_ATTACK_KNIFE;
    public static int AP_ATTACK_BLUDGEON;
    public static int AP_ATTACK_BATTLE_AX;

    public static int AP_ATTACK_PISTOL;
    public static int AP_SUBMACHINE_GUN;
    public static int AP_ATTACK_SHOTGUN;
    public static int AP_ATTACK_RIFLE;
    public static int AP_ATTACK_MACHINE;

    public static int AP_USE_FIRST_AID;
    public static int AP_USE_ELIXIR;

    public static int TIME_MOVE_BALL;
    public static int TIME_THROW_NEW_BALLS;
    public static int TIME_REMOVE_LINES;

    public static int TIME_REALTIME_MOVE_DELAY;
    public static int TIME_ATTACK_MELEE;
    public static int TIME_ATTACK_KNUCKLES;
    public static int TIME_ATTACK_KNIFE;
    public static int TIME_ATTACK_BLUDGEON;
    public static int TIME_ATTACK_BATTLE_AX;

    public static int TIME_ATTACK_PISTOL;
    public static int TIME_ATTACK_SUBMACHINE_GUN;
    public static int TIME_ATTACK_SHOTGUN;
    public static int TIME_ATTACK_RIFLE;
    public static int TIME_ATTACK_MACHINE;

    public static int TIME_USE_FIRST_AID;
    public static int TIME_USE_ELIXIR;

    public static int TIME_CHANGE_WEAPON;
    public static int TIME_RELOAD_WEAPON;

    public static int TIME_TURN_INTO_MORPH;
    public static int TIME_SUICIDE;

    public static boolean ATTACK_HIMSELF;
    public static boolean FRIENDLY_FIRE;

    public static int MAX_EVADE_COUNT;
    public static int MAX_CRIT_COUNT;

    public static int TICKS_BEFORE_BATTLE_START;

    public static int NEW_BALLS_COUNT;

    public static int LINE_LENGTH;

    // TELNET_CONFIG_FILE
    public static boolean TELNET_ENABLE;
    public static int TELNET_PORT;
    public static String TELNET_PASSWORD;
    public static String TELNET_LIST_OF_HOSTS;

    public static boolean LOG_OFF_USERS_WHEN_TOMCAT_RESTART;

    public static int ASTAR_MAX_ITERATIONS;


    public static final int TICKS_PER_SECOND = 10; // not able to change this without checking through code
    public static final int MILLIS_IN_TICK = 1000 / TICKS_PER_SECOND;

    /**
	 * This class initializes all global variables for configuration.<br>
	 * If the key doesn't appear in properties file, a default value is set by this class.
	 */
	public static void load()
	{
		if(Server.serverMode == Server.MODE_GAMESERVER)
		{
			_log.info("Loading GameServer Configuration Files...");
			InputStream is = null;
			try
			{
				try
				{
					PaperGamesProperties serverSettings = new PaperGamesProperties();

					is = Config.class.getResourceAsStream(CONFIGURATION_FILE);
					serverSettings.load(is);

                    PORT_FOR_WEB_SERVER = Integer.parseInt(serverSettings.getProperty("PortForWebServer", "3333"));
                    SELECTOR_THREAD_SLEEP_FOR_WEB_SERVER = Integer.parseInt(serverSettings.getProperty("SelectorThreadSleepForWebServer", "500"));

					GAMESERVER_HOSTNAME = serverSettings.getProperty("GameserverHostname");
					PORT_GAME = Integer.parseInt(serverSettings.getProperty("GameserverPort", "4444"));

					EXTERNAL_HOSTNAME = serverSettings.getProperty("ExternalHostname", "*");
					INTERNAL_HOSTNAME = serverSettings.getProperty("InternalHostname", "*");

					GAME_SERVER_LOGIN_PORT = Integer.parseInt(serverSettings.getProperty("LoginPort","9014"));
					GAME_SERVER_LOGIN_HOST = serverSettings.getProperty("LoginHost","127.0.0.1");

					REQUEST_ID = Integer.parseInt(serverSettings.getProperty("RequestServerID","0"));
					ACCEPT_ALTERNATE_ID = Boolean.parseBoolean(serverSettings.getProperty("AcceptAlternateID","True"));

					DATABASE_DRIVER = serverSettings.getProperty("Driver", "com.mysql.jdbc.Driver");
					DATABASE_URL = serverSettings.getProperty("URL", "jdbc:mysql://localhost/l2jdb");
					DATABASE_LOGIN = serverSettings.getProperty("Login", "root");
					DATABASE_PASSWORD = serverSettings.getProperty("Password", "");
					DATABASE_MAX_CONNECTIONS = Integer.parseInt(serverSettings.getProperty("MaximumDbConnections", "10"));
					DATABASE_MAX_IDLE_TIME = Integer.parseInt(serverSettings.getProperty("MaximumDbIdleTime", "0"));

					DATAPACK_ROOT = new File(serverSettings.getProperty("DatapackRoot", ".")).getCanonicalFile();

					CNAME_TEMPLATE = serverSettings.getProperty("CnameTemplate", ".*");
					PET_NAME_TEMPLATE = serverSettings.getProperty("PetNameTemplate", ".*");

					MAX_CHARACTERS_NUMBER_PER_ACCOUNT = Integer.parseInt(serverSettings.getProperty("CharMaxNumber", "0"));
					MAXIMUM_ONLINE_USERS = Integer.parseInt(serverSettings.getProperty("MaximumOnlineUsers", "100"));

                    DEADLOCK_DETECTOR = Boolean.parseBoolean(serverSettings.getProperty("DeadLockDetector", "False"));
                    DEADLOCK_CHECK_INTERVAL = Integer.parseInt(serverSettings.getProperty("DeadLockCheckInterval", "20"));
                    RESTART_ON_DEADLOCK = Boolean.parseBoolean(serverSettings.getProperty("RestartOnDeadlock", "False"));

                    THREAD_P_EFFECTS = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeEffects", "10"));
                    THREAD_P_GENERAL = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeGeneral", "13"));
                    IO_PACKET_THREAD_CORE_SIZE = Integer.parseInt(serverSettings.getProperty("UrgentPacketThreadCoreSize", "2"));
                    GENERAL_PACKET_THREAD_CORE_SIZE = Integer.parseInt(serverSettings.getProperty("GeneralPacketThreadCoreSize", "8"));
                    WS_PACKET_THREAD_CORE_SIZE = Integer.parseInt(serverSettings.getProperty("WsPacketThreadCoreSize", "4"));
                    GENERAL_THREAD_CORE_SIZE = Integer.parseInt(serverSettings.getProperty("GeneralThreadCoreSize", "4"));
                    AI_MAX_THREAD = Integer.parseInt(serverSettings.getProperty("AiMaxThread", "6"));

                    PACKET_HANDLER_DEBUG = Boolean.parseBoolean(serverSettings.getProperty("PacketHandlerDebug", "False"));

                    TURN_CONTROLLER_THREAD_COUNT = Integer.parseInt(serverSettings.getProperty("TurnControllerThreadCount", "2"));
                    BATTLE_COUNT_IN_ONE_TURN_CONTROLLER = Integer.parseInt(serverSettings.getProperty("BattleCountInOneTurnController", "500"));

                    CLIENT_SYNC_TIMEOUT = Long.parseLong(serverSettings.getProperty("clientSyncTimeout", "3000"));
                    BATTLE_INIT_TIMEOUT = Long.parseLong(serverSettings.getProperty("battleInitTimeout", "30000"));

                    NPC_CONTROLLER_THREAD_COUNT = Integer.parseInt(serverSettings.getProperty("NpcControllerThreadCount", "1"));
                    NPC_COUNT_IN_ONE_NPC_CONTROLLER = Integer.parseInt(serverSettings.getProperty("NpcCountInOneNpcController", "1000"));

                    AP_PER_TURN = Integer.parseInt(serverSettings.getProperty("ActionPointsPerTurn", "1"));
                    AP_MOVE_BALL = Integer.parseInt(serverSettings.getProperty("ActionPointsMoveBall", "1"));
                    AP_TOGGLE_DOOR = Integer.parseInt(serverSettings.getProperty("ActionPointsToggleDoor", "1"));
                    AP_EQUIP_ITEM = Integer.parseInt(serverSettings.getProperty("ActionPointsEquipItem", "1"));
                    AP_SWAP_WEAPONS = Integer.parseInt(serverSettings.getProperty("ActionPointsSwapWeapons", "1"));
                    AP_UNSEAL_CONTAINER = Integer.parseInt(serverSettings.getProperty("ActionPointsUnsealContainer", "1"));
                    AP_OPEN_CONTAINER = Integer.parseInt(serverSettings.getProperty("ActionPointsOpenContainer", "1"));
                    AP_EXCHANGE_ITEMS = Integer.parseInt(serverSettings.getProperty("ActionPointsExchangeItems", "1"));
                    AP_DROP = Integer.parseInt(serverSettings.getProperty("ActionPointsDrop", "2"));

                    AP_ATTACK_MELEE = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackMelee", "3"));
                    AP_ATTACK_KNUCKLES = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackKnuckles", "3"));
                    AP_ATTACK_KNIFE = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackKnife", "3"));
                    AP_ATTACK_BLUDGEON = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackBludgeon", "4"));
                    AP_ATTACK_BATTLE_AX = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackBattleAx", "4"));
                    AP_ATTACK_PISTOL = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackPistol", "3"));
                    AP_SUBMACHINE_GUN = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackSubMachineGun", "3"));
                    AP_ATTACK_SHOTGUN = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackShotGun", "3"));
                    AP_ATTACK_RIFLE = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackRifle", "4"));
                    AP_ATTACK_MACHINE = Integer.parseInt(serverSettings.getProperty("ActionPointsAttackMachine", "4"));

                    AP_USE_FIRST_AID = Integer.parseInt(serverSettings.getProperty("ActionPointsUseFirstAid", "1"));
                    AP_USE_ELIXIR = Integer.parseInt(serverSettings.getProperty("ActionPointsUseElixir", "1"));

                    ATTACK_HIMSELF = Boolean.parseBoolean(serverSettings.getProperty("AttackHimself", "false"));
                    FRIENDLY_FIRE = Boolean.parseBoolean(serverSettings.getProperty("FriendlyFire", "false"));

                    MAX_EVADE_COUNT = Integer.parseInt(serverSettings.getProperty("maxEvadeCount", "1"));
                    MAX_CRIT_COUNT = Integer.parseInt(serverSettings.getProperty("maxCritCount", "1"));

                    TICKS_BEFORE_BATTLE_START = Integer.parseInt(serverSettings.getProperty("ticksBeforeBattleStart", "30"));

                    NEW_BALLS_COUNT = Integer.parseInt(serverSettings.getProperty("newBallsCount", "6"));
                    LINE_LENGTH = Integer.parseInt(serverSettings.getProperty("lineLength", "4"));

                    TIME_MOVE_BALL = Integer.parseInt(serverSettings.getProperty("timeMoveBall", "500"));
                    TIME_THROW_NEW_BALLS = Integer.parseInt(serverSettings.getProperty("timeThrowNewBalls", "1000"));
                    TIME_REMOVE_LINES = Integer.parseInt(serverSettings.getProperty("timeRemoveLines", "300"));
                    TIME_REALTIME_MOVE_DELAY = Integer.parseInt(serverSettings.getProperty("timeRealtimeMoveDelay", "50"));
                    TIME_ATTACK_MELEE = Integer.parseInt(serverSettings.getProperty("timeAttackMelee", "250"));
                    TIME_ATTACK_KNUCKLES = Integer.parseInt(serverSettings.getProperty("timeAttackKnuckles", "250"));
                    TIME_ATTACK_KNIFE = Integer.parseInt(serverSettings.getProperty("timeAttackKnife", "250"));
                    TIME_ATTACK_BLUDGEON = Integer.parseInt(serverSettings.getProperty("timeAttackBludgeon", "400"));
                    TIME_ATTACK_BATTLE_AX = Integer.parseInt(serverSettings.getProperty("timeAttackBattleAx", "400"));
                    TIME_ATTACK_PISTOL = Integer.parseInt(serverSettings.getProperty("timeAttackPistol", "400"));
                    TIME_ATTACK_SUBMACHINE_GUN = Integer.parseInt(serverSettings.getProperty("timeAttackSubMachineGun", "400"));
                    TIME_ATTACK_SHOTGUN = Integer.parseInt(serverSettings.getProperty("timeAttackShotGun", "400"));
                    TIME_ATTACK_RIFLE = Integer.parseInt(serverSettings.getProperty("timeAttackRifle", "400"));
                    TIME_ATTACK_MACHINE = Integer.parseInt(serverSettings.getProperty("timeAttackMachine", "400"));

                    TIME_USE_FIRST_AID = Integer.parseInt(serverSettings.getProperty("timeUseFirstAid", "300"));
                    TIME_USE_ELIXIR = Integer.parseInt(serverSettings.getProperty("timeUseElixir", "300"));
                    TIME_CHANGE_WEAPON = Integer.parseInt(serverSettings.getProperty("timeChangeWeapon", "1200"));
                    TIME_RELOAD_WEAPON = Integer.parseInt(serverSettings.getProperty("timeReloadWeapon", "1200"));

                    TIME_TURN_INTO_MORPH = Integer.parseInt(serverSettings.getProperty("timeTurnIntoMorph", "1200"));
                    TIME_SUICIDE = Integer.parseInt(serverSettings.getProperty("timeSuicide", "1200"));

                    ASTAR_MAX_ITERATIONS = Integer.parseInt(serverSettings.getProperty("AstarMaxIterations", "350"));

                    LOG_OFF_USERS_WHEN_TOMCAT_RESTART = Boolean.parseBoolean(serverSettings.getProperty("logOffUsersWhenTomcatRestart", "false"));

				}
				catch (Exception e)
				{
					e.printStackTrace();
					throw new Error("Failed to Load "+CONFIGURATION_FILE+" File.");
				}

				// MMO
				try
				{
					_log.info("Loading " + MMO_CONFIG_FILE.replaceAll("./config/", ""));
					PaperGamesProperties mmoSettings = new PaperGamesProperties();
                    is = Config.class.getResourceAsStream(MMO_CONFIG_FILE);
					mmoSettings.load(is);
					MMO_SELECTOR_SLEEP_TIME = Integer.parseInt(mmoSettings.getProperty("SleepTime", "20"));
					MMO_IO_SELECTOR_THREAD_COUNT = Integer.parseInt(mmoSettings.getProperty("IOSelectorThreadCount", "2"));
					MMO_MAX_SEND_PER_PASS = Integer.parseInt(mmoSettings.getProperty("MaxSendPerPass", "12"));
					MMO_MAX_READ_PER_PASS = Integer.parseInt(mmoSettings.getProperty("MaxReadPerPass", "12"));
					MMO_HELPER_BUFFER_COUNT = Integer.parseInt(mmoSettings.getProperty("HelperBufferCount", "20"));
				}
				catch (Exception e)
				{
					e.printStackTrace();
					throw new Error("Failed to Load " + MMO_CONFIG_FILE + " File.");
				}

				// TELNET
				try
				{
					_log.info("Loading " + TELNET_CONFIG_FILE.replaceAll("./config/", ""));
					PaperGamesProperties telnetSettings = new PaperGamesProperties();
                    is = Config.class.getResourceAsStream(TELNET_CONFIG_FILE);
					telnetSettings.load(is);
					TELNET_ENABLE = Boolean.parseBoolean(telnetSettings.getProperty("EnableTelnet", "false"));
					TELNET_PORT = Integer.parseInt(telnetSettings.getProperty("GameStatusPort", "12345"));
					TELNET_PASSWORD = telnetSettings.getProperty("StatusPW", "");
					TELNET_LIST_OF_HOSTS = telnetSettings.getProperty("ListOfHosts", "localhost;127.0.0.1");
				}
				catch (Exception e)
				{
					e.printStackTrace();
					throw new Error("Failed to Load " + TELNET_CONFIG_FILE + " File.");
				}

				// Load FloodProtector L2Properties file
//				try
//				{
//					OsideGameProperties security = new OsideGameProperties();
//					is = new FileInputStream(new File(FLOOD_PROTECTOR_FILE));
//					security.load(is);
//
//					loadFloodProtectorConfigs(security);
//				}
//				catch (Exception e)
//				{
//					e.printStackTrace();
//					throw new Error("Failed to Load "+FLOOD_PROTECTOR_FILE);
//				}

			}
			finally
			{
				try
				{
					is.close();
				}
				catch (Exception e) { }
			}
		}
		else
		{
			_log.fatal("Could not Load Config: server mode was not set");
		}
	}

	private Config() { }

	/**
	 * Loads flood protector configurations.
	 */
	private static void loadFloodProtectorConfigs(final PaperGamesProperties properties)
	{
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_USE_ITEM, "UseItem", "4");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_ROLL_DICE, "RollDice", "42");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_FIREWORK, "Firework", "42");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_ITEM_PET_SUMMON, "ItemPetSummon", "16");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_HERO_VOICE, "HeroVoice", "100");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_GLOBAL_CHAT, "GlobalChat", "5");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_SUBCLASS, "Subclass", "20");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_DROP_ITEM, "DropItem", "10");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_SERVER_BYPASS, "ServerBypass", "5");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_MULTISELL, "MultiSell", "1");
		loadFloodProtectorConfig(properties, FLOOD_PROTECTOR_TRANSACTION, "Transaction", "10");
	}
	
	/**
	 * Loads single flood protector configuration.
	 * 
	 * @param properties
	 *            L2Properties file reader
	 * @param config
	 *            flood protector configuration instance
	 * @param configString
	 *            flood protector configuration string that determines for which flood protector
	 *            configuration should be read
	 * @param defaultInterval
	 *            default flood protector interval
	 */
	private static void loadFloodProtectorConfig(final PaperGamesProperties properties, final FloodProtectorConfig config, final String configString, final String defaultInterval)
	{
		config.FLOOD_PROTECTION_INTERVAL = Integer.parseInt(properties.getProperty(StringUtil.concat("FloodProtector", configString, "Interval"), defaultInterval));
		config.LOG_FLOODING = Boolean.parseBoolean(properties.getProperty(StringUtil.concat("FloodProtector", configString, "LogFlooding"), "False"));
		config.PUNISHMENT_LIMIT = Integer.parseInt(properties.getProperty(StringUtil.concat("FloodProtector", configString, "PunishmentLimit"), "0"));
		config.PUNISHMENT_TYPE = properties.getProperty(StringUtil.concat("FloodProtector", configString, "PunishmentType"), "none");
		config.PUNISHMENT_TIME = Integer.parseInt(properties.getProperty(StringUtil.concat("FloodProtector", configString, "PunishmentTime"), "0"));
	}
}
